package com.chengzhi.eshopinventory.thread;

import com.chengzhi.eshopinventory.request.BaseRequest;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.IntStream;

/**
 * @description thread pool
 * @author: ruanchengzhi
 * @create: 2021-04-01 15:17
 **/
public class RequestThreadPool {

    private static ThreadPoolExecutor defaultParallelExecutor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),
            Runtime.getRuntime().availableProcessors() * 2,
            30L, TimeUnit.SECONDS, new SynchronousQueue<>(),
            new ThreadPoolExecutor.CallerRunsPolicy());

    private List<ArrayBlockingQueue<BaseRequest>> queueList = new ArrayList<>(10);

    private ConcurrentHashMap<Long, Boolean> flagMap = new ConcurrentHashMap<>();

    public static void init() {
        getInstance();
    }

    public RequestThreadPool() {
        IntStream.range(0, 10).forEach(x -> {
            ArrayBlockingQueue<BaseRequest> blockingQueue = new ArrayBlockingQueue<>(100);
            queueList.add(blockingQueue);
            defaultParallelExecutor.submit(new WorkerThread(blockingQueue));
        });
    }

    public int getSize() {
        return queueList.size();
    }

    public ConcurrentHashMap<Long, Boolean> getFlagMap() {
        return flagMap;
    }

    public ArrayBlockingQueue<BaseRequest> get(int index) {
        if (index > queueList.size() || queueList.size() == 0) {
            throw new ArrayIndexOutOfBoundsException();
        }
        return queueList.get(index);
    }


    private static class Singleton {
        private static RequestThreadPool requestThreadPool;

        static {
            requestThreadPool = new RequestThreadPool();
        }

        private static RequestThreadPool getInstance() {
            return Singleton.requestThreadPool;
        }
    }

    public static RequestThreadPool getInstance() {
        return Singleton.getInstance();
    }
}
